package com.test.design.patternz;

/**
 * 工厂方法模式
 * 解决什么？
 * 在软件设计中，我们经常遇到需要创建不同类型对象的情况。但是，如果直接在代码中实例化对象，
 * 会使代码紧密耦合在一起，难以维护和扩展。此外，如果对象的创建方式需要变化，那么就需要在整个代码中进行大量的修改。
 * 工厂方法模式旨在解决这个问题。
 * 如何解决？
 * 工厂方法模式提供了一个创建对象的接口，但是将具体的对象创建延迟到子类中。这样，客户端代码不需要知道要创建的具体对象的类，
 * 只需要通过工厂方法来创建对象。这使得客户端代码与具体对象的创建解耦，提高了代码的灵活性和可维护性。
 * 在工厂方法模式中，通常会定义一个抽象工厂类，其中包含一个创建对象的抽象方法，而具体的对象创建则由具体的子类实现。
 * 这样，每个具体的子类都可以根据需要创建不同类型的对象，而客户端代码只需要通过抽象工厂类来调用工厂方法，而不需要关心具体的对象创建细节。
 * 有什么优点？
 * 松耦合：客户端代码与具体对象的创建解耦，使得系统更具弹性和可维护性。
 * 扩展性：通过添加新的具体工厂和产品子类，可以很容易地扩展系统以支持新的对象类型。
 * 封装性：将对象的创建集中在工厂类中，封装了对象的创建细节，使得客户端代码更简洁。
 */
public class FactoryMethodPattern {

    //创建图形类接口（提供一个创建对象接口，将具体对象延迟到子类中）
    interface Shape {
        void draw();
    }

    //图形类一：Circle（圆形）
    static class Circle implements Shape {
        @Override
        public void draw() {
            System.out.println("画了一个圆形");
        }
    }
    //图形类二： Rectangle（矩形）
    static class Rectangle implements Shape {
        @Override
        public void draw() {
            System.out.println("画了一个矩形");
        }
    }

    // 创建一个抽象工厂类 ShapeFactory
    // 它定义了一个抽象的工厂方法 createShape，子类将实现这个方法来创建具体的图形对象
    static abstract class ShapeFactory {
        abstract Shape createShape();
    }

    // 具体的工厂类: CircleFactory
    // 实现了 ShapeFactory 并重写了 createShape 方法来返回相应的图形对象
    static class CircleFactory extends ShapeFactory {
        @Override
        Shape createShape() {
            return new Circle();
        }
    }
    // 具体工厂类：RectangleFactory
    // 实现了 ShapeFactory 并重写了 createShape 方法来返回相应的图形对象
    static class RectangleFactory extends ShapeFactory {
        @Override
        Shape createShape() {
            return new Rectangle();
        }
    }

    //使用工厂类创建图形像
    public static void main(String[] args) {
//        ShapeFactory circleFactory = new CircleFactory();
//        Shape circle = circleFactory.createShape();
//        circle.draw();

        ShapeFactory rectangleFactory = new RectangleFactory();
        Shape rectangle = rectangleFactory.createShape();
        rectangle.draw();
    }
}
